Skip to content

ci(actions): GitHub Actions RTL/Web/WASM pipelines + Vercel deploy config (Phase 9) - #13

Merged
deaneeth merged 7 commits into
devfrom
ci/quality
Jun 5, 2026
Merged

ci(actions): GitHub Actions RTL/Web/WASM pipelines + Vercel deploy config (Phase 9)#13
deaneeth merged 7 commits into
devfrom
ci/quality

Conversation

@deaneeth

@deaneeth deaneeth commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds three GitHub Actions CI workflows: RTL CI (Verilator 5.036 built from source + full cocotb test suite), Web CI (pnpm lint/typecheck/build with pnpm store cache), WASM Build CI (emsdk + artifact existence assertion)
  • Adds web/vercel.json with explicit Content-Type: application/wasm and long-lived Cache-Control: immutable headers — without this Vercel serves the binary as text/html and the browser rejects the WASM module
  • Fixes 4 pre-existing ESLint errors in gen-og-image.mjs (unused fill variable + console/Buffer Node.js globals not configured) that would have failed Web CI on the very first run
  • Adds live CI status badge row to README beneath the tech-stack badges

Type of Change

  • ci — GitHub Actions change
  • chore — repo maintenance, CI, tooling
  • fix — bug fix
  • docs — documentation only

What Was Changed and Why

Key decisions

  • Verilator built from source in RTL CI: cocotb 2.x (installed in the venv) requires Verilator >= 5.036; Ubuntu 24.04 apt ships only 5.020. The build is pinned to tag v5.036 and cached by that tag so only the first CI run pays the ~5 min compile cost.
  • WASM CI uses apt Verilator 5.020: The WASM build path (verilator --ccem++) has no cocotb version gate, so the faster apt install is correct and sufficient there.
  • vercel.json lives in web/: Vercel root directory is configured as web/, so it reads vercel.json from there. The explicit MIME header for .wasm is required — without it Vercel serves the binary as text/html and the browser rejects the WASM module with a type error.
  • ESLint fix scoped to scripts/: Added globals.node only for scripts/**/*.mjs — not globally — to preserve browser-only type safety for all application source files.

RTL Changes

N/A — no RTL source files were modified.

Frontend Changes

  • pnpm lint — clean
  • pnpm typecheck — clean (0 errors, 0 warnings across 32 files)
  • pnpm build — clean, 7 pages built successfully

Testing

verilator --lint-only -Wall rtl/*.sv    # clean, zero warnings
pytest sim/golden.py -q                 # 4/4 passed
cd web && pnpm lint                     # clean
cd web && pnpm typecheck                # 0 errors, 0 warnings
cd web && pnpm build                    # 7 pages built

Branching Checklist

  • Branch created from dev
  • Target branch of this PR is dev
  • All commits follow Conventional Commits (ci:, docs:, chore:, fix:)
  • No large binaries committed
  • No secrets or credentials committed

Reviewer Notes

  • Local Verilator mismatch: The installed local Verilator (5.020) is below cocotb 2.x minimum (5.036). The full cocotb test suite (test_pe, test_systolic_array, test_top) can only run in CI until the local toolchain is upgraded by building Verilator from source. The golden model tests (pytest sim/golden.py) still run fine locally.
  • WASM artifacts must be committed: The WASM workflow asserts web/public/tiny_tpu.mjs and web/public/tiny_tpu.wasm exist. These were committed in Phase 5 and are present — the workflow will pass.
  • First RTL CI run will be slow: Verilator 5.036 will be compiled from source (~5 min). All subsequent runs hit the cache and run in seconds.

deaneeth added 6 commits June 5, 2026 21:21
Adds .github/workflows/rtl.yml, triggered on push/PR to rtl/** or sim/**.

Ubuntu 24.04 apt ships Verilator 5.020, but cocotb 2.x requires >= 5.036.
Build Verilator v5.036 from source on first run and cache the install prefix
by version tag so subsequent runs skip the ~5 min build step.

Steps:
  - Lint RTL with `verilator --lint-only -Wall rtl/*.sv`
  - Run `pytest sim/golden.py -q` (numpy golden reference)
  - cocotb test_pe, test_systolic_array, test_top via make (WAVES=0 for speed)

Removes .github/workflows/.gitkeep placeholder now that real files exist.
Adds .github/workflows/web.yml, triggered on push/PR to web/**.

Uses pnpm/action-setup@v4 (pnpm 11) + actions/setup-node@v4 (Node 22)
with `cache: pnpm` pointing at web/pnpm-lock.yaml to avoid full reinstalls
on unchanged dependencies.

Runs in order: pnpm install --frozen-lockfile, pnpm lint, pnpm typecheck,
pnpm build. All three must pass; build failure surfaces SSR/WASM import
errors that wouldn't otherwise be caught locally.
Adds .github/workflows/wasm.yml, triggered on push/PR to rtl/** or wasm/**.

Installs Verilator 5.020 from apt (sufficient for the WASM build path —
cocotb's version gate only applies to the simulation Makefile, not the
em++ compilation step) and Emscripten via mymindstorm/setup-emsdk@v14.

Runs wasm/build.sh and asserts both web/public/tiny_tpu.mjs and
web/public/tiny_tpu.wasm are produced. Does not commit artifacts from CI;
they must be committed manually after local rebuilds.
Adds a second badge row beneath the tech-stack badges with live status
links for the three new GitHub Actions workflows: RTL CI, Web CI, and
WASM Build. Badges link directly to the workflow run list so viewers
can inspect recent results without leaving the README.
Vercel may serve .wasm files as text/html without an explicit header rule,
which causes the browser to reject the module with a MIME type error and
shows a blank visualizer. The headers block pins Content-Type to
application/wasm for tiny_tpu.wasm and application/javascript for
tiny_tpu.mjs, ensuring correct browser parsing in production.

Also sets Cache-Control: immutable on both artifacts — they are content-
addressed by the WASM build process so long-lived caching is safe.

vercel.json is placed inside web/ (the configured Vercel root directory).
Two issues in the OG image generation script broke `pnpm lint`:

1. Unused variable: `fill` was computed in peCell() but the SVG template
   later switched to inline hardcoded hex values. Removed the dead
   declaration so no-unused-vars is satisfied.

2. Undeclared globals: `console` and `Buffer` are Node.js globals, but
   the ESLint config only injected browser + es2022 globals for .ts/.tsx
   files. Added a separate config block for scripts/**/*.mjs with
   globals.node so these built-ins are recognised without any
   eslint-disable comments.

`pnpm lint`, `pnpm typecheck`, and `pnpm build` all pass after this fix.
@deaneeth deaneeth added chore Maintenance and tooling ci GitHub Actions / CI changes docs Documentation only fix Bug fix labels Jun 5, 2026
@deaneeth deaneeth self-assigned this Jun 5, 2026
@deaneeth deaneeth changed the title ci: GitHub Actions RTL/Web/WASM pipelines + Vercel deploy config (Phase 9) ci(actions): GitHub Actions RTL/Web/WASM pipelines + Vercel deploy config (Phase 9) Jun 5, 2026
cocotb does not detect when TOPLEVEL changes between sequential make runs
sharing the same sim_build/ directory. The PE test compiled sim_build/Vtop
for module `pe`; the systolic array test then reused that binary and
crashed at runtime with "root handle systolic_array != pe".

Fix: pass SIM_BUILD=sim_build/<suite> to each make invocation so every
test suite compiles into its own isolated directory.
@deaneeth
deaneeth merged commit bbbf99a into dev Jun 5, 2026
4 checks passed
@deaneeth
deaneeth deleted the ci/quality branch June 5, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Maintenance and tooling ci GitHub Actions / CI changes docs Documentation only fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant